These forms create local macros and “symbol macros.”
This form is analogous to
flet, but for macros instead of functions. Each binding is a list of the same form as the arguments todefmacro*(i.e., a macro name, argument list, and macro-expander forms). The macro is defined accordingly for use within the body of themacrolet.Because of the nature of macros,
macroletis lexically scoped even in Emacs Lisp: Themacroletbinding will affect only calls that appear physically within the body forms, possibly after expansion of other macros in the body.
This form creates symbol macros, which are macros that look like variable references rather than function calls. Each binding is a list ‘(var expansion)’; any reference to var within the body forms is replaced by expansion.
(setq bar '(5 . 9)) (symbol-macrolet ((foo (car bar))) (incf foo)) bar ⇒ (6 . 9)A
setqof a symbol macro is treated the same as asetf. I.e.,(setq foo 4)in the above would be equivalent to(setf foo 4), which in turn expands to(setf (car bar) 4).Likewise, a
letorlet*binding a symbol macro is treated like aletforletf*. This differs from true Common Lisp, where the rules of lexical scoping cause aletbinding to shadow asymbol-macroletbinding. In this package, onlylexical-letandlexical-let*will shadow a symbol macro.There is no analogue of
defmacrofor symbol macros; all symbol macros are local. A typical use ofsymbol-macroletis in the expansion of another macro:(defmacro* my-dolist ((x list) &rest body) (let ((var (gensym))) (list 'loop 'for var 'on list 'do (list* 'symbol-macrolet (list (list x (list 'car var))) body)))) (setq mylist '(1 2 3 4)) (my-dolist (x mylist) (incf x)) mylist ⇒ (2 3 4 5)In this example, the
my-dolistmacro is similar todolist(see Iteration) except that the variablexbecomes a true reference onto the elements of the list. Themy-dolistcall shown here expands to(loop for G1234 on mylist do (symbol-macrolet ((x (car G1234))) (incf x)))which in turn expands to
(loop for G1234 on mylist do (incf (car G1234)))See Loop Facility, for a description of the
loopmacro. This package defines a nonstandardin-refloop clause that works much likemy-dolist.